repo-file: Base OstreeRepoFile on trees instead of commits
authorJasper St. Pierre <jstpierre@mecheye.net>
Sat, 7 Sep 2013 03:27:45 +0000 (23:27 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Tue, 10 Sep 2013 02:31:59 +0000 (22:31 -0400)
We want an OstreeRepoFile to be the way to represent a filesystem tree
inside an ostree repository. In order to do this, we need to drop the
commit from an OstreeRepoFile, and make that go to callers.

Switch all current users of ostree_repo_file_new_root to
ostree_repo_read_commit, and make the actual constructor private.

https://bugzilla.gnome.org/show_bug.cgi?id=707727

src/libgsystem
src/libostree/ostree-repo-file.c
src/libostree/ostree-repo-file.h
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo.c
src/ostree/ot-admin-deploy.c
src/ostree/ot-builtin-checkout.c

index 7b9901e3fc8aa58cf9c0579c29340506269ebfbd..bd2c1e436b270b39ca262765e775b4556d6bd50b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7b9901e3fc8aa58cf9c0579c29340506269ebfbd
+Subproject commit bd2c1e436b270b39ca262765e775b4556d6bd50b
index 048c2bc4fa6b47e6c73fe56392925b99bca482aa..d5f2a542d916b0929b3d3388c603cdfaa7190d49 100644 (file)
@@ -33,10 +33,6 @@ struct OstreeRepoFile
   GObject parent_instance;
 
   OstreeRepo *repo;
-
-  char *commit;
-  GError *commit_resolve_error;
-  
   OstreeRepoFile *parent;
   int index;
   char *name;
@@ -65,8 +61,6 @@ ostree_repo_file_finalize (GObject *object)
   g_free (self->cached_file_checksum);
   g_free (self->tree_contents_checksum);
   g_free (self->tree_metadata_checksum);
-  g_free (self->commit);
-  g_clear_error (&self->commit_resolve_error);
   g_free (self->name);
 
   G_OBJECT_CLASS (ostree_repo_file_parent_class)->finalize (object);
@@ -110,40 +104,30 @@ set_error_noent (GFile *self, GError **error)
   return FALSE;
 }
 
-/**
- * ostree_repo_file_new_root:
- * @repo: Containing repo
- * @commit: SHA256 checksum
- *
- * Returns: (transfer full): A new #OstreeRepoFile corresponding to commit contents
- */
-GFile * 
-ostree_repo_file_new_root (OstreeRepo  *repo,
-                            const char  *commit)
+static OstreeRepoFile *
+ostree_repo_file_new_root (OstreeRepo *repo,
+                           const char *contents_checksum,
+                           const char *metadata_checksum)
 {
   OstreeRepoFile *self;
 
   g_return_val_if_fail (repo != NULL, NULL);
-  g_return_val_if_fail (commit != NULL, NULL);
-  g_return_val_if_fail (strlen (commit) == 64, NULL);
+  g_return_val_if_fail (contents_checksum != NULL, NULL);
+  g_return_val_if_fail (strlen (contents_checksum) == 64, NULL);
+  g_return_val_if_fail (metadata_checksum != NULL, NULL);
+  g_return_val_if_fail (strlen (metadata_checksum) == 64, NULL);
 
   self = g_object_new (OSTREE_TYPE_REPO_FILE, NULL);
   self->repo = g_object_ref (repo);
-  self->commit = g_strdup (commit);
+  self->tree_contents_checksum = g_strdup (contents_checksum);
+  self->tree_metadata_checksum = g_strdup (metadata_checksum);
 
-  return G_FILE (self);
+  return self;
 }
 
-/**
- * ostree_repo_file_new_child:
- * @parent:
- * @name: Name for new child
- *
- * Returns: (transfer full): A new child file with the given name
- */
-GFile *
+static OstreeRepoFile *
 ostree_repo_file_new_child (OstreeRepoFile *parent,
-                             const char  *name)
+                            const char     *name)
 {
   OstreeRepoFile *self;
   size_t len;
@@ -156,51 +140,66 @@ ostree_repo_file_new_child (OstreeRepoFile *parent,
   if (self->name[len-1] == '/')
     self->name[len-1] = '\0';
 
-  return G_FILE (self);
+  return self;
 }
 
-static gboolean
-do_resolve_commit (OstreeRepoFile  *self,
-                   GError         **error)
+OstreeRepoFile *
+_ostree_repo_file_new_for_commit (OstreeRepo  *repo,
+                                  const char  *commit,
+                                  GError     **error)
 {
-  gboolean ret = FALSE;
-  gs_unref_variant GVariant *commit = NULL;
-  gs_unref_variant GVariant *root_contents = NULL;
-  gs_unref_variant GVariant *root_metadata = NULL;
+  OstreeRepoFile *ret = NULL;
+  gs_unref_variant GVariant *commit_v = NULL;
   gs_unref_variant GVariant *tree_contents_csum_v = NULL;
   gs_unref_variant GVariant *tree_metadata_csum_v = NULL;
-  char tmp_checksum[65];
+  char tree_contents_csum[65];
+  char tree_metadata_csum[65];
 
-  g_assert (self->parent == NULL);
+  g_return_val_if_fail (repo != NULL, NULL);
+  g_return_val_if_fail (commit != NULL, NULL);
+  g_return_val_if_fail (strlen (commit) == 64, NULL);
 
-  if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_COMMIT,
-                                 self->commit, &commit, error))
+  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
+                                 commit, &commit_v, error))
     goto out;
 
   /* PARSE OSTREE_OBJECT_TYPE_COMMIT */
-  g_variant_get_child (commit, 6, "@ay", &tree_contents_csum_v);
+  g_variant_get_child (commit_v, 6, "@ay", &tree_contents_csum_v);
+  ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_contents_csum_v),
+                                      tree_contents_csum);
+
+  g_variant_get_child (commit_v, 7, "@ay", &tree_metadata_csum_v);
+  ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_metadata_csum_v),
+                                      tree_metadata_csum);
 
-  ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_contents_csum_v), tmp_checksum);
+  ret = ostree_repo_file_new_root (repo, tree_contents_csum, tree_metadata_csum);
+
+ out:
+  return ret;
+}
+
+static gboolean
+do_resolve (OstreeRepoFile  *self,
+            GError         **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_variant GVariant *root_contents = NULL;
+  gs_unref_variant GVariant *root_metadata = NULL;
+
+  g_assert (self->parent == NULL);
 
   if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE,
-                                 tmp_checksum,
-                                 &root_contents, error))
+                                 self->tree_contents_checksum, &root_contents, error))
     goto out;
 
-  g_variant_get_child (commit, 7, "@ay", &tree_metadata_csum_v);
-  ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_metadata_csum_v), tmp_checksum);
-
   if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META,
-                                 tmp_checksum,
-                                 &root_metadata, error))
+                                 self->tree_metadata_checksum, &root_metadata, error))
     goto out;
   
   self->tree_metadata = root_metadata;
   root_metadata = NULL;
   self->tree_contents = root_contents;
   root_contents = NULL;
-  self->tree_contents_checksum = ostree_checksum_from_bytes_v (tree_contents_csum_v);
-  self->tree_metadata_checksum = ostree_checksum_from_bytes_v (tree_metadata_csum_v);
 
   ret = TRUE;
  out:
@@ -217,12 +216,15 @@ do_resolve_nonroot (OstreeRepoFile     *self,
   gs_unref_variant GVariant *container = NULL;
   gs_unref_variant GVariant *tree_contents = NULL;
   gs_unref_variant GVariant *tree_metadata = NULL;
-  gs_unref_variant GVariant *content_csum_v = NULL;
+  gs_unref_variant GVariant *contents_csum_v = NULL;
   gs_unref_variant GVariant *metadata_csum_v = NULL;
   gs_free char *tmp_checksum = NULL;
 
+  if (!ostree_repo_file_ensure_resolved (self->parent, error))
+    goto out;
+
   i = ostree_repo_file_tree_find_child (self->parent, self->name, &is_dir, &container);
-  
+
   if (i < 0)
     {
       set_error_noent ((GFile*)self, error);
@@ -239,15 +241,15 @@ do_resolve_nonroot (OstreeRepoFile     *self,
       g_clear_pointer (&files_variant, (GDestroyNotify) g_variant_unref);
 
       g_variant_get_child (container, i, "(&s@ay@ay)",
-                           &name, &content_csum_v, &metadata_csum_v);
+                           &name, &contents_csum_v, &metadata_csum_v);
 
       g_free (tmp_checksum);
-      tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v);
+      tmp_checksum = ostree_checksum_from_bytes_v (contents_csum_v);
       if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE,
                                      tmp_checksum, &tree_contents,
                                      error))
         goto out;
-          
+
       g_free (tmp_checksum);
       tmp_checksum = ostree_checksum_from_bytes_v (metadata_csum_v);
       if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META,
@@ -259,7 +261,7 @@ do_resolve_nonroot (OstreeRepoFile     *self,
       tree_contents = NULL;
       self->tree_metadata = tree_metadata;
       tree_metadata = NULL;
-      self->tree_contents_checksum = ostree_checksum_from_bytes_v (content_csum_v);
+      self->tree_contents_checksum = ostree_checksum_from_bytes_v (contents_csum_v);
       self->tree_metadata_checksum = ostree_checksum_from_bytes_v (metadata_csum_v);
     }
   else
@@ -274,36 +276,26 @@ gboolean
 ostree_repo_file_ensure_resolved (OstreeRepoFile  *self,
                                    GError         **error)
 {
-  if (self->commit_resolve_error != NULL)
-    goto out;
+  gboolean ret = FALSE;
 
   if (self->parent == NULL)
     {
       if (self->tree_contents == NULL)
-        (void)do_resolve_commit (self, &(self->commit_resolve_error));
-    }
-  else if (self->index == -1)
-    {
-      if (!ostree_repo_file_ensure_resolved (self->parent, error))
-        goto out;
-      (void)do_resolve_nonroot (self, &(self->commit_resolve_error));
+        if (!do_resolve (self, error))
+          goto out;
     }
-  
- out:
-  if (self->commit_resolve_error)
+  else
     {
-      if (error)
-       *error = g_error_copy (self->commit_resolve_error);
-      return FALSE;
+      if (self->index == -1)
+        {
+          if (!do_resolve_nonroot (self, error))
+            goto out;
+        }
     }
-  else
-    return TRUE;
-}
 
-const char *
-ostree_repo_file_get_commit (OstreeRepoFile  *self)
-{
-  return ostree_repo_file_get_root (self)->commit;
+  ret = TRUE;
+ out:
+  return ret;
 }
 
 gboolean
@@ -507,7 +499,10 @@ ostree_repo_file_get_uri (GFile *file)
   path = gs_file_get_path_cached (file);
   uri_path = g_filename_to_uri (path, NULL, NULL);
   g_assert (g_str_has_prefix (uri_path, "file://"));
-  ret = g_strconcat ("ostree://", self->commit, uri_path+strlen("file://"), NULL);
+  ret = g_strconcat ("ostree://",
+                     self->tree_contents_checksum, "/", self->tree_metadata_checksum,
+                     uri_path+strlen("file://"),
+                     NULL);
   g_free (uri_path);
 
   return ret;
@@ -533,9 +528,9 @@ ostree_repo_file_dup (GFile *file)
   OstreeRepoFile *self = OSTREE_REPO_FILE (file);
 
   if (self->parent)
-    return ostree_repo_file_new_child (self->parent, self->name);
+    return G_FILE (ostree_repo_file_new_child (self->parent, self->name));
   else
-    return ostree_repo_file_new_root (self->repo, self->commit);
+    return G_FILE (ostree_repo_file_new_root (self->repo, self->tree_contents_checksum, self->tree_metadata_checksum));
 }
 
 static guint
@@ -546,7 +541,7 @@ ostree_repo_file_hash (GFile *file)
   if (self->parent)
     return g_file_hash (self->parent) + g_str_hash (self->name);
   else
-    return g_str_hash (self->commit);
+    return g_str_hash (self->tree_contents_checksum) + g_str_hash (self->tree_metadata_checksum);
 }
 
 static gboolean
@@ -558,12 +553,13 @@ ostree_repo_file_equal (GFile *file1,
 
   if (self1->parent && self2->parent)
     {
-      return g_str_equal (self1->name, self2->name)
-        && g_file_equal ((GFile*)self1->parent, (GFile*)self2->parent);
+      return (g_str_equal (self1->name, self2->name) &&
+              g_file_equal ((GFile*)self1->parent, (GFile*)self2->parent));
     }
   else if (!self1->parent && !self2->parent)
     {
-      return g_str_equal (self1->commit, self2->commit);
+      return (g_str_equal (self1->tree_contents_checksum, self2->tree_contents_checksum) &&
+              g_str_equal (self1->tree_metadata_checksum, self2->tree_metadata_checksum));
     }
   else
     return FALSE;
@@ -654,7 +650,7 @@ ostree_repo_file_resolve_relative_path (GFile      *file,
   else
     filename = g_strdup (relative_path);
 
-  parent = (OstreeRepoFile*)ostree_repo_file_new_child (self, filename);
+  parent = ostree_repo_file_new_child (self, filename);
   g_free (filename);
     
   if (!rest)
index dc8c0bda2904c7770b6d7aea5fe6a00a6c991f5f..094ae2cffd0624af770cb1a11e6b1906cd033c64 100644 (file)
@@ -42,12 +42,6 @@ struct _OstreeRepoFileClass
 
 GType   ostree_repo_file_get_type (void) G_GNUC_CONST;
 
-GFile * ostree_repo_file_new_root (OstreeRepo  *repo,
-                                    const char  *commit);
-
-GFile * ostree_repo_file_new_child (OstreeRepoFile *parent,
-                                     const char  *name);
-
 gboolean ostree_repo_file_ensure_resolved (OstreeRepoFile  *self,
                                             GError         **error);
 
@@ -68,12 +62,11 @@ void ostree_repo_file_tree_set_metadata (OstreeRepoFile *self,
 const char *ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile  *self);
 const char *ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile  *self);
 
-gboolean ostree_repo_file_is_tree (OstreeRepoFile  *self);
+GVariant *ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
+GVariant *ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
 
 const char * ostree_repo_file_get_checksum (OstreeRepoFile  *self);
 
-const char * ostree_repo_file_get_commit (OstreeRepoFile  *self);
-
 int     ostree_repo_file_tree_find_child  (OstreeRepoFile  *self,
                                             const char      *name,
                                             gboolean        *is_dir,
@@ -87,8 +80,5 @@ gboolean ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
                                              GCancellable    *cancellable,
                                              GError         **error);
 
-GVariant *ostree_repo_file_tree_get_contents (OstreeRepoFile  *self);
-GVariant *ostree_repo_file_tree_get_metadata (OstreeRepoFile  *self);
-
 G_END_DECLS
 
index a3e8723db45711079c34b41e7aed5a64152a146a..fe9114b00ba9242dde0b0520568133cfb18f3605 100644 (file)
@@ -111,5 +111,10 @@ _ostree_repo_update_refs (OstreeRepo        *self,
                           GCancellable      *cancellable,
                           GError           **error);
 
+OstreeRepoFile *
+_ostree_repo_file_new_for_commit (OstreeRepo  *repo,
+                                  const char  *commit,
+                                  GError     **error);
+
 G_END_DECLS
 
index 5e1590bf4c37b130bab1d15bc705e747a39d13fd..81ffe8d5ee51e25ab7c97f8aa0c7f41193f8326f 100644 (file)
@@ -1413,18 +1413,21 @@ ostree_repo_read_commit (OstreeRepo *self,
                          GError **error)
 {
   gboolean ret = FALSE;
-  gs_unref_object GFile *ret_root = NULL;
+  gs_unref_object OstreeRepoFile *ret_root = NULL;
   gs_free char *resolved_rev = NULL;
 
   if (!ostree_repo_resolve_rev (self, rev, FALSE, &resolved_rev, error))
     goto out;
 
-  ret_root = ostree_repo_file_new_root (self, resolved_rev);
-  if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)ret_root, error))
+  ret_root = _ostree_repo_file_new_for_commit (self, resolved_rev, error);
+  if (!ret_root)
+    goto out;
+
+  if (!ostree_repo_file_ensure_resolved (ret_root, error))
     goto out;
 
   ret = TRUE;
-  ot_transfer_out_value(out_root, &ret_root);
+  ot_transfer_out_value(out_root, (GFile **) &ret_root);
  out:
   return ret;
 }
index 9379b50064183b034f4e40e3bcc308e4b2905942..575522eb64ce948c4fcf867f545dbc82e07e5780 100644 (file)
@@ -209,18 +209,17 @@ checkout_deployment_tree (GFile             *sysroot,
 {
   gboolean ret = FALSE;
   const char *csum = ot_deployment_get_csum (deployment);
-  gs_unref_object OstreeRepoFile *root = NULL;
+  gs_unref_object GFile *root = NULL;
   gs_unref_object GFileInfo *file_info = NULL;
   gs_free char *checkout_target_name = NULL;
   gs_unref_object GFile *osdeploy_path = NULL;
   gs_unref_object GFile *deploy_target_path = NULL;
   gs_unref_object GFile *deploy_parent = NULL;
 
-  root = (OstreeRepoFile*)ostree_repo_file_new_root (repo, csum);
-  if (!ostree_repo_file_ensure_resolved (root, error))
+  if (!ostree_repo_read_commit (repo, csum, &root, cancellable, error))
     goto out;
 
-  file_info = g_file_query_info ((GFile*)root, OSTREE_GIO_FAST_QUERYINFO,
+  file_info = g_file_query_info (root, OSTREE_GIO_FAST_QUERYINFO,
                                  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                  cancellable, error);
   if (!file_info)
@@ -239,7 +238,7 @@ checkout_deployment_tree (GFile             *sysroot,
   g_print ("ostadmin: Creating deployment %s\n",
            gs_file_get_path_cached (deploy_target_path));
 
-  if (!ostree_repo_checkout_tree (repo, 0, 0, deploy_target_path, root,
+  if (!ostree_repo_checkout_tree (repo, 0, 0, deploy_target_path, OSTREE_REPO_FILE (root),
                                   file_info, cancellable, error))
     goto out;
 
index 873e2c5dc15424f814b37c821f456c5c27bf46d2..b2284b43805884f1ad13e613113cf1e05ff6ff4b 100644 (file)
@@ -56,20 +56,19 @@ process_one_checkout (OstreeRepo           *repo,
 {
   gboolean ret = FALSE;
   GError *tmp_error = NULL;
-  gs_unref_object OstreeRepoFile *root = NULL;
-  gs_unref_object OstreeRepoFile *subtree = NULL;
+  gs_unref_object GFile *root = NULL;
+  gs_unref_object GFile *subtree = NULL;
   gs_unref_object GFileInfo *file_info = NULL;
 
-  root = (OstreeRepoFile*)ostree_repo_file_new_root (repo, resolved_commit);
-  if (!ostree_repo_file_ensure_resolved (root, error))
+  if (!ostree_repo_read_commit (repo, resolved_commit, &root, cancellable, error))
     goto out;
-  
+
   if (subpath)
-    subtree = (OstreeRepoFile*)g_file_resolve_relative_path ((GFile*)root, subpath);
+    subtree = g_file_resolve_relative_path (root, subpath);
   else
     subtree = g_object_ref (root);
 
-  file_info = g_file_query_info ((GFile*)subtree, OSTREE_GIO_FAST_QUERYINFO,
+  file_info = g_file_query_info (subtree, OSTREE_GIO_FAST_QUERYINFO,
                                  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                  cancellable, &tmp_error);
   if (!file_info)
@@ -89,7 +88,7 @@ process_one_checkout (OstreeRepo           *repo,
 
   if (!ostree_repo_checkout_tree (repo, opt_user_mode ? OSTREE_REPO_CHECKOUT_MODE_USER : 0,
                                   opt_union ? OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES : 0,
-                                  target, subtree, file_info, cancellable, error))
+                                  target, OSTREE_REPO_FILE (subtree), file_info, cancellable, error))
     goto out;
                       
   ret = TRUE;